<script setup>
import {inject, ref, reactive, onMounted, nextTick, watch} from 'vue'
import { useMessage } from 'jiuqi-ui'
import {getTreeNodeById, scrollIntoView} from "../../../utils/TreeHelper";
import IconEnum from "../../../utils/iconEnum";
import {Debounce} from "../../../utils/debounce";
//================================================【公用相关】============================================================
//提示信息组件
const message = useMessage()
//发送请求组件
const context = inject('context')

//表单绑定数据
const folderItem = reactive({ id: '', title: '', pId: '',type:''})
//================================================【组件通信】============================================================
const props = defineProps(['addFolderFlag'])
//控制 标签分组处理对话框 显示与隐藏
const folderEditorDialogVisible = inject('folderEditorDialogVisible')
//获取 标签分组信息
const { folderInfo, callback } = inject('labelFolder', null)

//================================================【组件属性】============================================================
//监听 标签分组处理对话框  显示与否
watch(folderEditorDialogVisible,(newValue)=>{
    if (newValue) {
        // 判断是新增还是编辑
        if (props.addFolderFlag) {
            folderItem.id = ''
            folderItem.pId = folderInfo.id
            folderItem.type = folderInfo.id === 'JIUQI_BASEDATA_LABEL' ? folderInfo.id : folderInfo.type

        } else {
            folderItem.id = folderInfo.id
            folderItem.title = folderInfo.title
            folderItem.pId = folderInfo.pId
        }
    }
},{immediate:true})
//================================================【普通方法】============================================================
//==================================================================【树形相关】
//树形分组节点数组
const folderTreeData = reactive([])
//原有所属标签分组树形展示数据副本
const preBelongLabelFolderTreeData = reactive([])
//所属标签分组树形是否处于搜索状态
const isBelongLabelFolderSearching = ref(false)
//当前处理标签分组  的  父分组
let selectedParentFolder =reactive({})
//默认展示数据节点,点击“所属分组”树形逐级展开后,选中的节点。
//后期在树形中点击其他节点时，需要取消默认展示数据节点的选中状态
const defaultSeletedNode = ref(null)
//树形节点选择
function nodeSelected(node){
    if( defaultSeletedNode.value){
        defaultSeletedNode.value.selected =false
    }
    if (node.selected) {
        folderItem.pId = node.id
        folderItem.type = node.type
        node.belongLabelFolderSelected = true
    }
}
//获取标签分组树形根节点
function getFolderTreeRootNode() {
    return new Promise((resolve) => {
        context.getPlugin('http').get("labelmanager/label/group/tree?pId=").then((res) => {
            folderTreeData.splice(0,folderTreeData.length,...res.data)
            resolve()
        });
    });
}
//树形异步加载
//当pathIndex存在时，按父组件传来的路径逐级展开树形节点
function loadFolderTreeData(item,pathIndex){

    return new Promise((resolve) => {
        if (item.expand) {
            return
        } else {
            context.getPlugin('http').get(`labelmanager/label/group/tree?pId=${item.id}`).then((res) => {
                const nodeDataArr = []
                if (res.data.length === 0) {
                    item.expand = true
                }
                for (let i = 0; i < res.data.length; i++) {
                    const nodeData = res.data[i];
                    // 当前分组自身  不应该  出现在待选择的新分组树形中
                    if(nodeData.id === folderInfo.id){
                        continue
                    }
                    // 叶子节点
                    if (nodeData.isLeaf) {
                        nodeData.expand = true
                    } else {
                        nodeData.loading = false
                        nodeData.expand = false
                    }
                    nodeDataArr.push(nodeData)
                }


              let treeNodeById = getTreeNodeById(folderTreeData, item.id)
              if (!treeNodeById.children) treeNodeById.children = reactive([])
              treeNodeById.children.push(...reactive(nodeDataArr))
              resolve(nodeDataArr)
              treeNodeById.expand = true
                if(pathIndex !== undefined){
                    expandPath(pathIndex+1)
                }
            })
        }
    })
}
//按父组件传来的路径逐级展开
function expandPath(pathIndex){
    //不存在路径信息，则不执行
    if(!folderInfo.path){
        return
    }

    //准备数据
    if(pathIndex < folderInfo.path.length){
        const nodeId = folderInfo.path[pathIndex]
        const targetNode = getTreeNodeById(folderTreeData,nodeId)
        if(targetNode){
            loadFolderTreeData(targetNode,pathIndex)
        }

        //数据准备完成，开始处理数据
    }else{
        //当前分组的分组id
        const pId = folderInfo.pId
        if(pId){
            const targetNode = getTreeNodeById(folderTreeData,pId)
            if(targetNode){
                targetNode.selected =true
                targetNode.belongLabelFolderSelected = true
                selectedParentFolder.id = targetNode.id
                selectedParentFolder.title = targetNode.title
                defaultSeletedNode.value= targetNode
            }
        }
    }
}

//对 所属标签分组树形 进行模糊搜索
function belongLabelFolderTreeSearch(searchValue){
    if (searchValue !== ''){
        if (!isBelongLabelFolderSearching.value) {
            preBelongLabelFolderTreeData.splice(0,preBelongLabelFolderTreeData.length,...folderTreeData)
            isBelongLabelFolderSearching.value = true
        }
        return new Promise((resolve) => {
            Debounce(  context.getPlugin('http').get('labelmanager/label/group/fuzzyMatch?keyWord='+searchValue).then((res) => {

                folderTreeData.splice(
                    0,
                    folderTreeData.length,
                    ...res.data.filter(preFilterItem=>{
                                        return preFilterItem.id !== folderItem.id})
                                .map(item => ({...item, isLeaf: undefined})));
                resolve()
            }),300)
        })
    }else {
        return new Promise((resolve) => {
            //对于输入中文的场景，当中文还未输入完成（输入框中还是拼音时）也会触发搜索，此时不替换显示数据（因为此时副本还没有填充数据）
            if (preBelongLabelFolderTreeData.length !== 0)
                folderTreeData.splice(0,folderTreeData.length,...preBelongLabelFolderTreeData)

            isBelongLabelFolderSearching.value = false
            resolve()
        })
    }
}
//==================================================================【表单相关】
//表单ref
const folderform = ref(null)
const rules = {
    title: [
        {
            required: true,
            message: '请输入分组标题'
        }, {
            asyncValidator: (rule, value) => {
                return new Promise((resolve, reject) => {
                    if (value.length > 50) {
                        reject('标题长度不能超过50个字符')
                    } else if (/\.$/.test(value)) {
                        reject('标题不能以.结尾')
                    } else if (/[/\\*<>"'\\|?:]/.test(value)) {
                        reject('标题不能包含\\ 、/ 、: 、* 、? 、" 、\' 、< 、> 、|中任意字符')
                    } else {
                        context.getPlugin('http').post('labelmanager/label/group/check/title', folderItem,{async:false}).then(res => {
                            if (res.data) {
                                reject('同一分组下，标题不允许重复')
                            } else {
                                resolve()
                            }
                        })
                    }
                })
            }
        }
    ],
    pId: [{
        asyncValidator: (rule, value) => {
            return new Promise((resolve, reject) => {
                // 编辑（移动分组）模式下校验
                if (!props.addFolderFlag &&  (value === null || value === undefined)) {
                    reject('请选择所属分组')
                } else {
                    resolve()
                }
            })
        }
    }]
}
//==================================================================【模态框相关】
//取消
function cancel() {
    folderEditorDialogVisible.value = false
}

//是否开启 加载状态
const confirmLoading = ref(false)
//确认
function saveFolder() {
    if(confirmLoading.value){
        return;
    }
    confirmLoading.value = true
    folderform.value.validate().then(validateResult =>{
        if (validateResult == null) {
            context.getPlugin('http').post('labelmanager/label/group/save', folderItem)
                .then((res) => {
                    confirmLoading.value = false
                    callback.saveLabelFolderBack(res.data.labelFolder,res.data.path)
                    folderItem.value = { id: '', title: '', pId: '' }
                    message.success(props.addFolderFlag ? '新建成功' : '编辑成功')
                    folderEditorDialogVisible.value = false
                }).catch((err) => {
                message.error(err.response.data.message)
                confirmLoading.value = false
            })
        }else{
            confirmLoading.value = false
        }
    })
}
//================================================【生命周期】============================================================
onMounted(() => {
    if(!props.addFolderFlag){
        nextTick(() =>{
            getFolderTreeRootNode().then(()=>{
                expandPath(0)
            })
        })
    }
})
</script>

<template>
  <j-modal
        v-model="folderEditorDialogVisible"
        :title="props.addFolderFlag ? '新建分组' : '编辑分组'"
        :fullscreenable='false'
        :closable="!confirmLoading"
        :mask-closable="false"
        :mask="false"
  >
    <j-modal-content size="small" class="modalContent" :class="props.addFolderFlag?'addModal':'modifyModal'">
      <j-form ref="folderform" :model="folderItem" :rules ="rules" label-position="right" :label-width="props.addFolderFlag? 40:70">
          <j-form-item label="标题" prop="title" required>
            <j-input v-model="folderItem.title" auto-focus placeholder="请输入标题" long></j-input>
          </j-form-item>
          <j-form-item label="所属分组" prop="pId" v-if="!props.addFolderFlag" required>
              <j-tree-select
                      :tree-data="folderTreeData"
                      :load-data="loadFolderTreeData"
                      v-model="selectedParentFolder"
                      :search="true"
                      :search-method="belongLabelFolderTreeSearch"
                      @change="nodeSelected"
                      @visible="scrollIntoView('belongLabelFolderSelected')"
                      :multiple="false"
                      placeholder="请选择所属分组">
                <template #node="{ title,belongLabelFolderSelected }">
                  <j-space :size="8">
                    <span :class=" 'nvwa-iconfont' + IconEnum.notLeaf"></span>
                    <span :class="belongLabelFolderSelected? ' belongLabelFolderSelected':''">{{ title }}</span>
                  </j-space>
                </template>
              </j-tree-select>
          </j-form-item>
        </j-form>
      </j-modal-content>
      <template #footer>
          <j-space style="justify-content: flex-end">
            <j-button @click="cancel" :disabled="confirmLoading">取消</j-button>
            <j-button type="primary" :loading="confirmLoading" @click="saveFolder">确定</j-button>
          </j-space>
      </template>
  </j-modal>
</template>
<style scoped>
.modalContent{
  padding: 16px 24px 16px 10px;
}
.addModal{
    height: 70px !important;
}
.modifyModal{
    height: 125px !important;
}
</style>
